
package com.hlkj.pay.gateway.order.impl;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.extension.executor.ExtensionExecutor;
import com.hlkj.framework.extension.scenario.BizScenario;
import com.hlkj.pay.app.merchant.ext.ChannelMerchantWithdrawExtPt;
import com.hlkj.pay.app.merchant.ext.MerchantExtConstant;
import com.hlkj.pay.app.merchant.ext.dto.payment.ChannelWithdrawContext;
import com.hlkj.pay.common.constants.MerchantConstant;
import com.hlkj.pay.dto.order.NotifyOrderWithdrawDto;
import com.hlkj.pay.enums.MerchantEnum;
import com.hlkj.pay.gateway.order.IChannelWithdrawGateway;
import com.hlkj.pay.infrastructure.model.merchant.MerchantAppChannelDO;
import com.hlkj.pay.infrastructure.model.order.OrderWithdrawDO;
import com.hlkj.pay.infrastructure.model.pay.ProviderChannelConfigDO;
import com.hlkj.pay.service.merchant.IMerchantApplicationService;
import com.hlkj.pay.service.pay.IProviderService;

import jodd.util.StringPool;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * @author HlpayTeam
 * @date 2025/02/10 14:38
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ChannelWithdrawGatewayImpl implements IChannelWithdrawGateway {

    @Value("${hlkj.pay.barrier:false}")
    private boolean barrier;

    @Value("${hlkj.pay.test:false}")
    private boolean test;

    @Value("${hlkj.domain}")
    private String domain;

    private final ExtensionExecutor extensionExecutor;

    private final IMerchantApplicationService merchantApplicationService;

    private final IProviderService providerService;

    @Override
    public boolean extensionExist(String channelCode) {
        return extensionExecutor.executeExist(ChannelMerchantWithdrawExtPt.class, BizScenario.valueOf(channelCode));
    }

    @Override
    public OrderWithdrawDO queryChannelOrder(OrderWithdrawDO orderWithdrawDO) {
        if (barrier) {
            OrderWithdrawDO orderWithdraw = new OrderWithdrawDO();
            orderWithdraw.setStatus(MerchantEnum.PROCESS_STATUS.SUCCESS.getCode());
            log.info("测试环境渠道不生成特殊订单号返回成功 payOrderNo:{}", orderWithdraw.getPayOrderNo());
            return orderWithdraw;
        }
        MerchantAppChannelDO merchantAppChannelDO = merchantApplicationService.queryAppChannelDetail(orderWithdrawDO.getMchChannelCode());
        ChannelWithdrawContext channelTransferContext = new ChannelWithdrawContext();
        channelTransferContext.setMerchantAppChannelDO(merchantAppChannelDO);
        channelTransferContext.setProviderChannelConfig(providerService.queryConfig(merchantAppChannelDO.getProviderCode(), merchantAppChannelDO.getChannelCode()));
        channelTransferContext.setOrderWithdraw(orderWithdrawDO);
        channelTransferContext.setTest(test);
        extensionExecutor.executeVoid(ChannelMerchantWithdrawExtPt.class, BizScenario.valueOf(merchantAppChannelDO.getChannelCode()),
                ex -> ex.queryChannelWithdraw(channelTransferContext));
        if (channelTransferContext.isProcessStatus()) {
            return channelTransferContext.getUpdateOrderWithdraw();
        }
        OrderWithdrawDO orderWithdraw = new OrderWithdrawDO();
        orderWithdraw.setStatus(MerchantEnum.PROCESS_STATUS.FAIL.getCode());
        orderWithdraw.setMessage(channelTransferContext.getRemark());
        return orderWithdraw;
    }

    @Override
    public CommonResult<NotifyOrderWithdrawDto> orderStatusParse(HttpServletRequest request, ProviderChannelConfigDO providerChannelConfigDO) {
        return extensionExecutor.execute(ChannelMerchantWithdrawExtPt.class, BizScenario.valueOf(providerChannelConfigDO.getChannelCode()),
                ex -> ex.orderWithdrawStatusParse(request, providerChannelConfigDO));
    }

    @Override
    public CommonResult<OrderWithdrawDO> submitWithdrawOrder(MerchantAppChannelDO merchantAppChannelDO, OrderWithdrawDO orderWithdrawDO) {
        if (barrier) {
            OrderWithdrawDO orderTransfer = new OrderWithdrawDO();
            orderTransfer.setStatus(MerchantEnum.PROCESS_STATUS.SUCCESS.getCode());
            log.info("测试环境提交转账预订单 返回成功 payOrderNo:{}", orderTransfer.getPayOrderNo());
            return CommonResult.success(orderTransfer);
        }
        ChannelWithdrawContext channelTransferContext = new ChannelWithdrawContext();
        channelTransferContext.setMerchantAppChannelDO(merchantAppChannelDO);
        channelTransferContext.setOrderWithdraw(orderWithdrawDO);
        channelTransferContext.setProviderChannelConfig(providerService.queryConfig(merchantAppChannelDO.getProviderCode(), merchantAppChannelDO.getChannelCode()));
        channelTransferContext.setTest(test);
        channelTransferContext.setNotifyUrl(domain + MerchantExtConstant.MERCHANT_TRANSFER_WITHDRAW_ASYNC_CALLBACK_URL + merchantAppChannelDO.getChannelCode() + StringPool.SLASH
                + merchantAppChannelDO.getProviderCode());
        channelTransferContext.setPassword(MerchantConstant.REPORT_PASSWORD);
        extensionExecutor.executeVoid(ChannelMerchantWithdrawExtPt.class, BizScenario.valueOf(merchantAppChannelDO.getChannelCode()),
                ex -> ex.submitChannelWithdraw(channelTransferContext));
        if (channelTransferContext.isProcessStatus()) {
            return CommonResult.success(channelTransferContext.getUpdateOrderWithdraw());
        }
        return CommonResult.error(1, channelTransferContext.getRemark());
    }
}
